package com.naiterui.common.repository.page;

import java.io.Serializable;

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.util.Assert;

import io.swagger.annotations.ApiModelProperty;

/**
 * Controller层通用的分页参数封装
 * 为了能在持久层中使用Spring-data-JPA的Pageable对象，实现了Pageable接口，并通过代理Pageable对象完成相关功能
 * 构建PageParamVO对象时，在内部构建了一个Pageable对象
 * 在构建分页参数的时候多为语义化的场景(第一页为1)，但在实际执行分页查询的时候是根据偏移量(第一页为0)进行操作的，
 * Spring-data-JPA的Pageable对象是基于offset的场景，因此为了能够兼容两种场景的切换，在构建分页参数对象时
 * 进行了处理
 * <P>File name : PageParamVO.java </P>
 * <P>Author : zhouyanxin </P>
 * <P>Date : 2017-08-21 </P>
 */
@SuppressWarnings("unused")
public class PageParamVO implements Serializable {

    /**
     * 字段或域定义：<code>serialVersionUID</code>
     */
    private static final long serialVersionUID = 5286136799619243513L;

    /**
     * 默认每页记录数
     */
    private static final int DEFAULT_PAGE_SIZE = 10;

    /**
     * 页码
     */
    @ApiModelProperty("页码")
    private int page = 1;

    /**
     * 每页记录数
     */
    @ApiModelProperty("每页记录数")
    private int num = DEFAULT_PAGE_SIZE;

    @ApiModelProperty("第一次分页的总记录数")
    private int offset = 0;

    /**
     * 构造函数
     */
    public PageParamVO() {

    }

    /**
     * 构造函数
     */
    public PageParamVO(int page, int num) {
        this.page = page;
        this.num = num;
    }

    /**
     * @return int 取得域 page 的方法。
     */
    public int getPage() {
        // return page <= 0 ? 1 : page;
        return this.page;
    }

    /**
     * @param page 对域 page 的设置方法.
     */
    public void setPage(int page) {
        this.page = page;
    }

    /**
     * @return int 取得域 num 的方法。
     */
    public int getNum() {
        return this.num <= 0 ? DEFAULT_PAGE_SIZE : this.num;
    }

    /**
     * @param num 对域 num 的设置方法.
     */
    public void setNum(int num) {
        this.num = num;
    }

    public int getOffset() {
        return this.offset;
    }

    public void setOffset(int offset) {
        this.offset = offset;
    }

    /**
     * 获取JPA分页对象
     *
     * @return 返回Pageable对象
     */
    public Pageable getPageable() {
        return PageRequest.of(this.getPage() == 0 ? 0 : this.getPage() - 1, this.getNum());
    }

    public Pageable getPageable(Sort sort) {
        Assert.notNull(sort, "排序规则不能为null");
        return PageRequest.of(this.getPage() == 0 ? 0 : this.getPage() - 1, this.getNum(), sort);
    }

    @Override
    public String toString() {
        return "PageParamVO{" + "page=" + this.page + ", num=" + this.num + ", offset=" + this.offset + '}';
    }

}
